using System;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine;
using SCG.SolarVengeanceEngine.BrainInfo;

namespace SCG.SolarVengeance.Brains
{
    public class LittleDragon2 : Brain
    {

        public override string Author
        {
            get { return "Ugly Green Things"; }
        }

        public override ChallengeLevel Challenge
        {
            get
            {
                return ChallengeLevel.Moderate;
            }
        }

        public override string Description
        {
            get { return "Little Dragon V2.5.1.4 Primary coding is to assault StarSystems with many WarShips, and builds Techships to support that effort.  When the cluster has enough value, it begins to build TechShips, InkSpots, and Startillery.  Added SpyShip build and order logic.  Added Drone build and defense logic.  Has the code to order E-Mines.  Upgraded defense logic."; }
        }

        //private members
        //private StarSystemInfo _capital;
        private int MaxWeaponValue = 0;
        private int MinWpn = 5;

        //Establish base list of ships that the brain can build
        public override List<StarShipType> AvailableShipTypes
        {
            get
            {
                List<StarShipType> shipTypes = new List<StarShipType>();
                shipTypes.Add(StarShipType.WarShip);
                shipTypes.Add(StarShipType.Drone);
                shipTypes.Add(StarShipType.TechShip);
                shipTypes.Add(StarShipType.StarTillery);
                shipTypes.Add(StarShipType.InkSpot);
                shipTypes.Add(StarShipType.SpyShip);
                return shipTypes;
            }
        }

//---------------------------------------Administrative Section--------------------------------------------------------------------

        //Executable Brain Logic
        public override void Execute()
        {
            //Count StarSystem Values 
            int sysValue = 0;
            foreach (StarSystemInfo sys in StarSystems)
                if (sys.OwnedByMe)
                    if (!sys.IsCapital)
                        sysValue += sys.Value;

            //Count Ship Types Built
            int NumTech = 0;
            int NumWarShip = 0;
            int NumStarTillery = 0;
            int NumSpyShips = 0;
            int STtoSSratio = 0;
            foreach (StarShipInfo sh in StarShips)
            {
                if (sh.OwnedByMe)
                {
                    if (sh.ShipType == StarShipType.TechShip)
                        NumTech++;
                    if (sh.ShipType == StarShipType.WarShip)
                        NumWarShip++;
                    if (sh.ShipType == StarShipType.StarTillery)
                        NumStarTillery++;
                    if (sh.ShipType == StarShipType.SpyShip)
                        NumSpyShips++;
                    STtoSSratio = (NumStarTillery + 1) / (NumSpyShips + 1);
                }
                //Warship Intelligence Section
                else if (sh.OwnedByMe == false)
                {
                    if ((sh.IdentifiedByMe == false) | (sh.ShipType == StarShipType.WarShip))
                        if (sh.KnownWeapons >= MinWpn)
                        {
                            MaxWeaponValue = sh.KnownWeapons;
                            MinWpn = MaxWeaponValue + 1;
                        }
                    if (sh.Value >= MinWpn)
                    {
                        MaxWeaponValue = sh.Value;
                        MinWpn = MaxWeaponValue + 1;
                    }
                }
            }

//-----------------------------------StarSystem Build Logic---------------------------------------------------------------------

            foreach (StarSystemInfo sys in StarSystems)
                if (sys.OwnedByMe)
                {
                    if (sys.IsCapital)
                    {
                        //Capital Build Normal
                        if (sysValue <= 80)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, 10, 5, false);
                            SetAutoStarShip(sys, true);
                        }

                        //Capital Build Advanced
                        if (sysValue > 80 && sysValue <= 140)
                        {
                            //Set Autobuild to OFF
                            if (sys.AutoStarShip == true)
                                SetAutoStarShip(sys, false);

                            //------------------Defense Logic

                            StarShipInfo AttackingShip = ClosestStarShip(sys.X, sys.Y, 6, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            StarShipInfo CloseShip = ClosestStarShip(sys.X, sys.Y, 9, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (AttackingShip != null)
                            {
                                SetAutoShields(sys, true);
                                SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                            }
                            else if (CloseShip != null)
                            {
                                SetAutoShields(sys, false);
                                SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                            }
                            else
                            {
                                SetAutoShields(sys, false);
                                SetAutoStarShipType(sys, StarShipType.WarShip, 10, Random(5, MinWpn), false);
                            }
                               //Defense Logic

                            if (NumWarShip <= 10) //If brain is being brutalized

                                SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, true);
                            SetAutoStarShip(sys, true);
                        }

                        //Capital Build Power-up
                        if (sysValue > 140)
                        {
                            //Set Autobuild to OFF
                            if (sys.AutoStarShip == true)
                                SetAutoStarShip(sys, false);

                            //---------------Defense Logic

                            StarShipInfo AttackingShip = ClosestStarShip(sys.X, sys.Y, 6, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            StarShipInfo CloseShip = ClosestStarShip(sys.X, sys.Y, 9, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (AttackingShip != null)
                            {
                                SetAutoShields(sys, true);
                                SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                            }
                            else if (CloseShip != null)
                            {
                                SetAutoShields(sys, false);
                                SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                            }
                            else
                            {
                                SetAutoShields(sys, false);
                                SetAutoStarShipType(sys, StarShipType.WarShip, 10, 5, false);
                            }

                            //SpyShip Build Logic
                            if (NumWarShip > 15 && STtoSSratio > 30)
                            {
                                BuildStarShip(sys, StarShipType.SpyShip, 20, 15, true);
                            }
                            //Power-up Warship Logic
                            if (NumWarShip >= 30 && STtoSSratio < 30)
                            {
                                BuildStarShip(sys, StarShipType.WarShip, 20, Random(5, MinWpn), true);
                            
                            }
                            //Power-up Startillery Logic
                            if (NumWarShip < 30 && STtoSSratio < 30)  //If brain is being brutalized
                            {
                                BuildStarShip(sys, StarShipType.StarTillery, 20, 8, true);
                            }
                            //Defense Logic
                            if (NumWarShip <= 10 && STtoSSratio < 15)  //If brain is being brutalized
                            {
                                BuildStarShip(sys, StarShipType.Drone, 6, 0, true);
                            }
                        }
                    }
                    else if (sys.IsCapital == false)
                    {
                        //----------------Defense Logic
                        
                            StarShipInfo AttackingShip = ClosestStarShip(sys.X,sys.Y,6,FindShipFlags.Enemy,ShipKnownFlags.Either);
                            StarShipInfo CloseShip = ClosestStarShip(sys.X, sys.Y, 9, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (AttackingShip != null) 
                                {
                                    SetAutoShields(sys, true);
                                    SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                                }
                            else if (CloseShip != null) 
                                {
                                    SetAutoShields(sys, false);
                                    SetAutoStarShipType(sys, StarShipType.Drone, 6, 0, false);
                                }
                            else 
                                {
                                    SetAutoShields(sys, false);
                                    SetAutoStarShipType(sys, StarShipType.WarShip, 10, 5, false);
                                }

                        //----------------Techship Build Logic
                        if (sys.Value < 11 && NumTech <= 51)
                        {
                            SetAutoStarShipType(sys, StarShipType.TechShip, 3, 0, false);
                            SetAutoStarShip(sys, true);
                        }

                        //------------------Alternate Low-end V10 Build Logic
                        if (sys.Value < 11 && NumTech <= 25 && NumWarShip < 15)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, Random(5, 8), Random(3, 5), false);
                            SetAutoStarShip(sys, true);
                        }

                        //-----------------Alternate High-end V10 Build Logic
                        if (sys.Value > 7 && sys.Value < 11 && NumTech > 25 && NumWarShip > 25)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, Random(8, 15), Random(5, 10), false);
                            SetAutoStarShip(sys, true);
                        }

                        //-----------------Default WarShip Build Logic
                        if (sys.Value >= 11 && sysValue < 140 && NumTech < 20)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, 10, 5, false);
                            SetAutoStarShip(sys, true);
                        }

                        //-----------------Power-Up WarShip Build Logic
                        if (sys.Value > 7 && sysValue > 140 && NumTech >= 50)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, Random(8, 20), Random(5, MinWpn), false);
                            SetAutoStarShip(sys, true);
                        }

                        //-----------------Cloaked StarTillery Build Logic
                        if (sys.Value > 16 && sysValue > 140 && NumTech > 40)
                        {
                            SetAutoStarShipType(sys, StarShipType.StarTillery, 20, Random(8, 15), true);
                            SetAutoStarShip(sys, true);
                        }

                        //-----------------Power-Up StarTillery Build Logic
                        if (sys.Value > 16 && sysValue > 140)
                        {
                            SetAutoStarShipType(sys, StarShipType.StarTillery, 20, Random(8, 15), false);
                            SetAutoStarShip(sys, true);
                        }
                         
                        //------------------Power-up InkSpot Build Logic
                        if (sys.Value <= 7 && NumTech > 50 && NumWarShip >= 30)
                        {
                            SetAutoStarShipType(sys, StarShipType.InkSpot, 10, 0, true);
                            SetAutoStarShip(sys, true);
                        }
                        //------------------Power-up Drone Build Logic
                        if (sys.Value < 5 && NumTech > 50 && NumWarShip >= 30)
                        {
                            SetAutoStarShipType(sys, StarShipType.Drone, 10, 0, true);
                            SetAutoStarShip(sys, true);
                        }
                        if (sys.AutoStarShip == false)
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, Random(8, 15), Random(5, MinWpn), true);
                            SetAutoStarShip(sys, true);
                        }
                    }
                
                }

//--------------------------------Starship Movement-Targeting Logic----------------------------------------------------------

            double TargDist = 0;
            bool TargetPosX = false;
            bool TargetPosY = false;
            int TargetX = 0;
            int TargetY = 0;

            foreach (StarShipInfo sh in MyStarShips)
            {
                //-----------Warship Targeting Logic
                if (sh.ShipType == StarShipType.WarShip)
                {
                    StarSystemInfo tgt = ClosestStarSystem(sh.X, sh.Y, 999, FindSystemFlags.Unfriendly);
                    Target(sh, tgt);
                }
                //-------------InkSpot Targeting Logic
                else if (sh.ShipType == StarShipType.InkSpot)
                {
                    //target closest enemy ship

                    StarShipInfo isTarg = ClosestStarShip(sh.X, sh.Y, Int32.MaxValue, FindShipFlags.Enemy, ShipKnownFlags.Either);
                    if (isTarg != null)
                        Move(sh, isTarg.X + Random(-4, 4), isTarg.Y + Random(-4, 4));

                    //else, swarm closest enemy starsystem

                    else
                    {
                        StarSystemInfo targetSys = ClosestStarSystem(sh.X, sh.Y, Int32.MaxValue, FindSystemFlags.Unfriendly);
                        if (targetSys != null)
                            Move(sh, targetSys.X + Random(-4, 4), targetSys.Y + Random(-4, 4));
                        else
                            Move(sh, sh.X + Random(-4, 4), sh.Y + Random(-4, 4));
                    }
                }
                //-------------TechShip Movement Code
                else if (sh.ShipType == StarShipType.TechShip)
                {
                    int dx = sh.X < MapWidth / 2 ? 0 : MapWidth - 1;
                    int dy = sh.Y < MapHeight / 2 ? 0 : MapHeight - 1;
                    Move(sh, dx, dy);
                }
                //---------------Drone Movement Code
                else if (sh.ShipType == StarShipType.Drone)
                {
                    StarSystemInfo dfd = ClosestStarSystem(sh.X, sh.Y, 999, FindSystemFlags.Unfriendly);
                    Defend(sh, dfd);
                }
                //---------------EMine Movement Code
                else if (sh.ShipType == StarShipType.EMine)
                {
                    StarSystemInfo dfe = ClosestStarSystem(sh.X, sh.Y, 999, FindSystemFlags.Unfriendly);
                    Defend(sh, dfe);
                }
                //---------------Startillery Targeting Code
                else if (sh.ShipType == StarShipType.StarTillery)
                {
                    //Target Closest Enemy Ship
                    StarShipInfo stTarg = ClosestStarShip(sh.X, sh.Y, 32767, FindShipFlags.Enemy, ShipKnownFlags.Either);
                    if (stTarg != null)
                    {

                        TargDist = Distance(sh.X, sh.Y, stTarg.X, stTarg.Y);

                        if (stTarg.X < MapWidth / 2)
                            //True indicates target starship located on the left half of the map.
                            TargetPosX = true;
                        
                        if (stTarg.X >= MapWidth / 2 )
                            //False indicates target starship located on the right half of the map.
                            TargetPosX = false;

                        if (stTarg.Y < MapHeight / 2)
                            //True indicates target starship located on the lower half of the map.
                            TargetPosY = true;

                        if (stTarg.Y >= MapHeight / 2)
                            //False indicates target starship located on the upper half of the map.
                            TargetPosY = false; 

                        //Horizontal Positioning Code

                        if (TargDist <= 6 && TargetPosX == true)
                            TargetX = stTarg.X + 4 ;  //short range
                       
                        if (TargDist <= 6 && TargetPosX == false)          
                            TargetX = stTarg.X - 4;  //short range

                        if (TargDist > 6 && TargDist <= 10 && TargetPosX == true)                      
                            TargetX = stTarg.X + 5 ;  //medium range

                        if (TargDist > 6 && TargDist <= 10 && TargetPosX == false)                       
                            TargetX = stTarg.X - 5;  //medium range
                        
                        if (TargDist > 10 && TargetPosX == true)                       
                            TargetX = stTarg.X + 8;  //long range
                        
                        if (TargDist > 10 && TargetPosX == false)                     
                            TargetX = stTarg.X - 8;  //long range

                        //Vertical Positioning Code

                        if (TargDist <= 6 && TargetPosY == true)
                            TargetY = stTarg.Y + 4;  //short range

                        if (TargDist <= 6 && TargetPosY == false)
                            TargetY = stTarg.Y - 4;  //short range

                        if (TargDist > 6 && TargDist <= 10 && TargetPosY == true)
                            TargetY = stTarg.Y + 5;  //medium range

                        if (TargDist > 6 && TargDist <= 10 && TargetPosY == false)
                            TargetY = stTarg.Y - 5;  //medium range

                        if (TargDist > 10 && TargetPosY == true)
                            TargetY = stTarg.Y + 8;  //long range

                        if (TargDist > 10 && TargetPosY == false)
                            TargetY = stTarg.Y - 8;  //long range
                        
                        Move(sh, TargetX, TargetY);
                    }

                    else  //Else, move out of the way so more ships can be built
                        Move(sh, sh.X + Random(-1, 1), sh.Y + Random(-1, 1));

                }
                //---------------SpyShip Movement Code
                else if (sh.ShipType == StarShipType.SpyShip)
                {
                    //Target Closest Enemy Ship
                    StarShipInfo spTarg = ClosestStarShip(sh.X, sh.Y, 32767, FindShipFlags.Enemy, ShipKnownFlags.Either);
                    if (spTarg != null)
                    {

                        TargDist = Distance(sh.X, sh.Y, spTarg.X, spTarg.Y);

                        if (spTarg.X < MapWidth / 2)
                            //True indicates target starship located on the left half of the map.
                            TargetPosX = true;

                        if (spTarg.X >= MapWidth / 2)
                            //False indicates target starship located on the right half of the map.
                            TargetPosX = false;

                        if (spTarg.Y < MapHeight / 2)
                            //True indicates target starship located on the lower half of the map.
                            TargetPosY = true;

                        if (spTarg.Y >= MapHeight / 2)
                            //False indicates target starship located on the upper half of the map.
                            TargetPosY = false;

                        //Horizontal Positioning Code

                        if (TargDist <= 5 && TargetPosX == true)
                            TargetX = spTarg.X + 6;  //short range

                        if (TargDist <= 5 && TargetPosX == false)
                            TargetX = spTarg.X - 6;  //short range

                        if (TargDist > 5 && TargDist <= 10 && TargetPosX == true)
                            TargetX = spTarg.X + 6;  //medium range

                        if (TargDist > 5 && TargDist <= 10 && TargetPosX == false)
                            TargetX = spTarg.X - 6;  //medium range

                        if (TargDist > 10 && TargetPosX == true)
                            TargetX = spTarg.X + 9;  //long range

                        if (TargDist > 10 && TargetPosX == false)
                            TargetX = spTarg.X - 9;  //long range

                        //Vertical Positioning Code

                        if (TargDist <= 5 && TargetPosY == true)
                            TargetY = spTarg.Y + 6;  //short range

                        if (TargDist <= 5 && TargetPosY == false)
                            TargetY = spTarg.Y - 6;  //short range

                        if (TargDist > 5 && TargDist <= 10 && TargetPosY == true)
                            TargetY = spTarg.Y + 6;  //medium range

                        if (TargDist > 5 && TargDist <= 10 && TargetPosY == false)
                            TargetY = spTarg.Y - 6;  //medium range

                        if (TargDist > 10 && TargetPosY == true)
                            TargetY = spTarg.Y + 9;  //long range

                        if (TargDist > 10 && TargetPosY == false)
                            TargetY = spTarg.Y - 9;  //long range

                        Move(sh, TargetX, TargetY);
                    }

                    else  //Else, move out of the way so more ships can be built
                        Move(sh, sh.X + Random(-4, 4), sh.Y + Random(-4, 4));

                }
            }    
         }
    }
}
